/* Project temp_hume_serial02
PIC16F877
*/

#include <pic.h>



__CONFIG(
PWRTEN
& BORDIS
& UNPROTECT
& WDTDIS
& LVPDIS
& HS
);

__IDLOC(F877);

#define E RB6


#define XON 17
#define XOFF 19

unsigned char xf;
unsigned char rbuf[16];
unsigned char wp;
unsigned char rp;
unsigned char dc;



void lcd_w_com4(unsigned char d){
PORTB = d & 0x0f;
E = 1; NOP();
E = 0;
}

void lcd_w_chr4(unsigned char d){
PORTB = (d & 0x0f) | 0x10;
E = 1; NOP();
E = 0;
}

void lcd_bfck(void){
unsigned char d;

PORTB = 0;
TRISB3 = 1;
PORTB = 0b00100000;

do{
E = 1; NOP();
d = RB3;
E = 0;
NOP(); NOP();
E = 1; NOP();
E = 0;
NOP(); NOP();
} while(d);

PORTB = 0;
TRISB3 = 0;
}

void lcd_putcom(unsigned char d){
lcd_bfck();
lcd_w_com4(d >> 4);
lcd_w_com4(d);
}

void lcd_locate(
unsigned char x, unsigned char y){
lcd_putcom((x + 0x40 * y) | 0x80);
}

void lcd_putchr(unsigned char d){
lcd_bfck();
lcd_w_chr4(d >> 4);
lcd_w_chr4(d);
}

void lcd_puts(const unsigned char *s){
while(*s) lcd_putchr(*s++);
}

unsigned int bresenham(
unsigned int n,unsigned int m,unsigned int d
){
unsigned int e;
unsigned int s;

s = e = 0;
while(n--){
e += m;
while(e >= d){
e -= d;
s++;
}
}
return s;
}


void lcd_putT(unsigned int v){

unsigned char i;
unsigned char buf[4];

v = bresenham(v - 116,518,10);

for(i = 0; i < 4; i++)
buf[i] = '0';
i = 3;
do {
buf[i] = (v % 10) + '0';
v = v / 10;
i--;
} while(v > 0);

if(buf[0] > 0) lcd_putchr(buf[0]);
else lcd_putchr(' ');
lcd_putchr(buf[1]);
lcd_putchr('.');
lcd_putchr(buf[2]);
lcd_puts("C");
}


void lcd_putH(unsigned int v){

unsigned char i;
unsigned char buf[4];


v = bresenham(v - 3,197,10);

for(i = 0; i < 4; i++)
buf[i] = '0';
i = 3;
do {
buf[i] = (v % 10) + '0';
v = v / 10;
i--;
} while(v > 0);

if(buf[0] > 0) lcd_putchr(buf[0]);
else lcd_putchr(' ');
lcd_putchr(buf[1]);
lcd_putchr('.');
lcd_putchr(buf[2]);
lcd_puts("%");
}



void interrupt entry(void){
unsigned char c;

if(RCIF){
c = RCREG;
if(c == XON || c == XOFF){
xf = c;
return;
}

if(dc == 16) return;
rbuf[wp] = c;
wp++;
wp &= 15;
dc++;
if(dc == 12){
while(TXIF == 0);
TXREG = XOFF;
}
}
}

unsigned char getchr(void){
unsigned char c;

while(dc == 0);
RCIE = 0;
c = rbuf[rp];
rp++;
rp &= 15;
dc --;
if(dc == 12){
while(TXIF == 0);
TXREG = XON;
}
RCIE = 1;
return(c);
}

void putchr(unsigned char c){
while(xf == XOFF);
while(TXIF == 0);
TXREG = c;
}

void put(const unsigned char *s){
while(*s) putchr(*s++);
}

void putui(
unsigned int ui, unsigned char d){

unsigned char i;
unsigned char buf[5];

for(i = 0; i < 5; i++)
buf[i] = ' ';
i = 4;
do {
buf[i] = (ui % 10) + '0';
ui = ui / 10;
i--;
} while(ui > 0);

for(i = (5 - d); i < 5; i++)
putchr(buf[i]);
}

void putui_dot(unsigned int v){
unsigned char i;
unsigned char buf[4];

for(i = 0; i < 4; i++)
buf[i] = '0';
i = 3;
do {
buf[i] = (v % 10) + '0';
v = v / 10;
i--;
} while(v > 0);

if(buf[0] > 0) putchr(buf[0]);
else putchr(' ');
putchr(buf[1]);
putchr('.');
putchr(buf[2]);
}




void main(void){

unsigned int v;
unsigned int v0, v1;


OPTION = 0b10000111; // 1/256
PORTB = 0;
TRISB = 0b10000000;
ADCON1 = 0b10000100;
ADCON0 = 0b10000001;

PORTA = 0;
TRISA = 0b00001011;

PORTC = 0;
TRISC = 0b10000000;


//CCP for PWM
PR2 = 153; // 1kHz
T2CON = 0b00000110; // TMR2 1/16
CCPR1L = 75;
CCP1CON = 0b00001100;

//sci
SPBRG = 128;
TXSTA = 0b00100100;
RCSTA = 0b10010000;

wp = 0;
rp = 0;
dc = 0;
xf = XON;

RCIE = 1;
PEIE = 1;
ei();



TMR0 = 0; while(TMR0 < 255);
lcd_w_com4(0x03);
TMR0 = 0; while(TMR0 < 80);
lcd_w_com4(0x03);
TMR0 = 0; while(TMR0 < 2);
lcd_w_com4(0x03);
TMR0 = 0; while(TMR0 < 2);
lcd_w_com4(0x02);

lcd_putcom(0x28);
lcd_putcom(0x01);
lcd_putcom(0x0c);

lcd_puts("TEMP HUME");


put("\n");
put(" time(s) ");
put(" Temp(c)");
put(" Hume(%)");
put("\n");
put("\n");



unsigned int k, k0;
k = 0;
k0 = 0;

while(1){

k = k + 1;
k0 = k * 10;
put(" ");
putui(k0,5);


unsigned char j;
for(j = 0; j < 15; j++){

//Channel 0
ADCON0 = 0b10000001;
TMR0 = 0; while(TMR0 < 100);
GODONE = 1;
while(GODONE);

v = (ADRESH * 256) + ADRESL;
if(v != v0){
v0 = v;
lcd_locate(0, 1);
lcd_putT(v0);
}

//Cannel 1
ADCON0 = 0b10001001;
TMR0 = 0; while(TMR0 < 100);
GODONE = 1;
while(GODONE);

v = (ADRESH * 256) + ADRESL;
if(v != v1){
v1 = v;
lcd_locate(7, 1);
lcd_putH(v1);
}

unsigned char i;
for(i = 0; i < 25; i++){
TMR0 = 0;
while(TMR0 < 234);
}

}


v0 = bresenham(v0 - 116,518,10);
put(" ");
putui_dot(v0);
put(" ");

v1 = bresenham(v1 - 3,197,10);
putui_dot(v1);
put("\n");



}

}